﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using System.Data;
using System.Reflection;

namespace ProjectBuilder
{
    abstract class BaseRefObject : BaseObject
    {

        public string Parent { get; set; }

        public void Save()
        {
            var cmd = new MySqlCommand();
            //int parentId = Class.getIdByName(Parent);
            var fields = getFields(this);

            var db = this.getAttribute<DbTableAttribute>();
            if (db == null)
            {
                throw new Exception("Unknown table name");
            }

            var query = "SELECT COUNT(*) FROM `" + db.TableName + "` WHERE 1 = 1";
            foreach (var field in fields)
            {
                if (field.Key == "new" || field.Key == "build_id") continue;
                query += " AND `" + field.Key + "` = @" + field.Key;
            }
            getQueryField(fields, ref cmd);
            cmd.CommandText = query;
            cmd.CommandType = CommandType.Text;
            cmd.Connection = Globals.Connection;
            int count = int.Parse(cmd.ExecuteScalar().ToString());

            if (count > 0)
            {
                query = "UPDATE `" + db.TableName + "` SET ";
                cmd = new MySqlCommand();
                var values = getQueryField(fields, ref cmd);
                var lst = new List<string>();
                foreach (var itm in values)
                {
                    if (itm.Key == "new") continue;

                    lst.Add(itm.Key + " = " + itm.Value);
                }
                query += string.Join(", ", lst.ToArray()) + " WHERE 1 = 1";
                foreach (var field in fields)
                {
                    if (field.Key == "new" || field.Key == "build_id") continue;
                    query += " AND `" + field.Key + "` = @" + field.Key;
                }               
                cmd.CommandText = query;
                cmd.CommandType = CommandType.Text;
                cmd.Connection = Globals.Connection;
                cmd.ExecuteNonQuery();
            }
            else
            {
                var keys = new List<string>(fields.Keys);
                var names = "`" + string.Join("`, `", keys.ToArray()) + "`";
                var parameters = "@" + string.Join(", @", keys.ToArray());

                query = "INSERT INTO `" + db.TableName + "`(" + names + ") VALUES (";

                cmd = new MySqlCommand();
                var values = getQueryField(fields, ref cmd);
                query += string.Join(",", values.Values.ToArray());
                query += ");";

                cmd.CommandText = query;
                cmd.CommandType = CommandType.Text;
                cmd.Connection = Globals.Connection;
                cmd.ExecuteNonQuery();
            }
        }

        /// <summary>
        /// Генерує список полів і їх значень для запису вставки/оновлення
        /// </summary>
        /// <param name="fields">поля</param>
        /// <param name="cmd">команда куди додавати поля</param>
        /// <returns>список полів(ключ-значення)</returns>
        protected Dictionary<string, string> getQueryField(Dictionary<string, object> fields, ref MySqlCommand cmd)
        {
            var values = new Dictionary<string, string>();
            foreach (var field in fields)
            {
                var val = "@" + field.Key;
                switch (field.Key)
                {
                    case "parent_id":
                        val = Class.getIdByName(field.Value.ToString()).ToString();
                        cmd.Parameters.AddWithValue(field.Key, val);
                        break;
                    case "new":
                        val = "1";
                        break;
                    /*case "update_time":
                        val = "FROM_UNIXTIME(" + Globals.Project.BuildId.ToUnixTime() + ")";
                        break;*/
                    case "build_id":
                        val = Globals.Project.BuildId.ToString();
                        break;
                    default:
                        cmd.Parameters.AddWithValue(field.Key, field.Value);
                        break;
                }
                values.Add(field.Key, val);
            }
            return values;
        }
    }
}
